﻿using System.Collections.Generic;
using System.Linq;
using Missbot.Common;
using Missbot.Core.Base;
using Dolany.UtilityTool;
using JetBrains.Annotations;
using Missbot.AIModule.Base;
using Missbot.AIModule.OnlineStore;
using Missbot.Core.Cache;

namespace Missbot.AIModule.Pet.Cooking
{
    [UsedImplicitly]
    public class CookingMod : IAIModule
    {
        public override string Name => "烹饪";
        public override string ParentTag => "宠物功能";

        #region Svcs

        public CookingDietSvc CookingDietSvc { get; set; }
        public WaiterSvc WaiterSvc { get; set; }
        public CookingLevelSvc CookingLevelSvc { get; set; }
        public HonorSvc HonorSvc { get; set; }

        #endregion

        [ModuleEnter(Command = "烹饪 烹饪菜肴 制作菜肴", Description = "开始烹饪一道指定的菜肴", SyntaxHint = "[菜肴名]")]
        public bool Cook(InboxSession session, string name)
        {
            var Diet = CookingDietSvc[name];
            if (Diet == null)
            {
                session.SendBack("未查找到相关菜肴名称！");
                return false;
            }

            var pet = PetRecordDA.Get(session.User.ID);
            if (pet.Level < Diet.Level)
            {
                session.SendBack($"{pet.Name}的等级太低，还不能烹饪该菜肴！({pet.Level}/{Diet.Level})");
                return false;
            }

            var cookingRec = CookingRecordDA.Get(session.User.ID);
            if (cookingRec.LearndDietMenu.IsNullOrEmpty() || !cookingRec.LearndDietMenu.Contains(Diet.Name))
            {
                session.SendBack($"你尚未学会{Diet.Name}的烹饪方法！(可使用【{Diet.ExchangeHonor}】兑换，详情请参见【帮助 兑换菜谱】)");
                return false;
            }

            var falvoringNeedStr = string.Join(",", Diet.Flavorings.Select(f => $"{f.Key}({cookingRec.FlavoringDic.GetDicValueSafe(f.Key)}/{f.Value})"));
            if (!Diet.Flavorings.IsNullOrEmpty() && !cookingRec.CheckFlavorings(Diet.Flavorings))
            {
                session.SendBack($"调味料不足！({falvoringNeedStr})");
                return false;
            }

            var itemColle = ItemCollectionDA.Get(session.User.ID);
            var allitems = itemColle.AllItemsDic();
            var materialNeedStr = string.Join(",", Diet.Materials.Select(m => $"{m.Key}({allitems.GetDicValueSafe(m.Key)}/{m.Value})"));
            if (!Diet.Materials.IsNullOrEmpty() && !itemColle.CheckItem(Diet.Materials))
            {
                session.SendBack($"材料不足！({materialNeedStr})");
                return false;
            }

            var msg = $"烹饪 {Diet.Name} 将需要消耗\n{falvoringNeedStr}\n{materialNeedStr}\n是否确认？";
            if (!WaiterSvc.WaitForConfirm(session, msg))
            {
                session.SendBack("操作取消！");
                return false;
            }

            cookingRec.FlavoringConsume(Diet.Flavorings);
            itemColle.ItemConsume(Diet.Materials);

            cookingRec.AddDiet(Diet.Name);

            cookingRec.Update();
            itemColle.Update();

            session.SendBack("烹饪成功！");
            return true;
        }

        [ModuleEnter(Command = "查看菜肴", Description = "查看指定菜肴的详细情况", SyntaxHint = "[菜肴名]")]
        public bool ViewDiet(InboxSession session, string name)
        {
            var Diet = CookingDietSvc[name];
            if (Diet == null)
            {
                session.SendBack("未查找到相关菜肴名称！");
                return false;
            }

            session.SendBack(Diet.Format());
            return true;
        }

        [ModuleEnter(Command = "我的烹饪记录", Description = "查看自己的历史烹饪情况")]
        public bool MyCookingHistory(InboxSession session)
        {
            var cookingRec = CookingRecordDA.Get(session.User.ID);
            var history = cookingRec.CookingHistory;
            if (history.IsNullOrEmpty())
            {
                session.SendBack("你尚未烹饪过任何东西！");
                return false;
            }

            var sumDietCount = history.Sum(p => p.Value);
            var totalPrice = cookingRec.TotalPrice();

            var curLevel = CookingLevelSvc.LocationLevel(totalPrice);
            var nextLevel = CookingLevelSvc[curLevel.Level + 1];

            var buffer = new OutputBuffer(session);
            buffer.Add($"你总共烹饪过 {sumDietCount} 道菜肴");
            buffer.Add($"总共消耗了物品 {cookingRec.ItemConsumeDic().Sum(p => p.Value)} 个，调味料 {cookingRec.FlavoringTotal()} 个");
            buffer.AddPair("总价值", totalPrice.CurencyFormat());
            buffer.AddPair("当前烹饪评级为", $"【{curLevel.Name}(lv.{curLevel.Level})】");
            buffer.Add($"距离下一等级【{nextLevel.Name}({nextLevel.Level})】还差 {(nextLevel.NeedPrice - totalPrice).CurencyFormat()}");
            buffer.Send();
            return true;
        }

        [ModuleEnter(Command = "兑换菜谱 学习菜谱", Description = "兑换指定的菜谱", SyntaxHint = "[菜谱名]")]
        public bool ExchangeMenu(InboxSession session, string name)
        {
            var diet = CookingDietSvc[name];
            if (diet == null)
            {
                session.SendBack("未查找到相关菜肴");
                return false;
            }

            var cookingRec = CookingRecordDA.Get(session.User.ID);
            if (cookingRec.LearndDietMenu.Contains(diet.Name))
            {
                session.SendBack("你已经学会了该菜肴的烹饪方法！");
                return false;
            }

            var itemColle = ItemCollectionDA.Get(session.User.ID);
            var honorModel = HonorSvc.FindHonor(diet.ExchangeHonor);
            var items = honorModel.Items.ToDictionary(p => p.Name, _ => 1);
            if (!itemColle.CheckItem(items))
            {
                session.SendBack($"你尚未集齐【{diet.ExchangeHonor}】的所有物品！");
                return false;
            }

            itemColle.ItemConsume(items);
            itemColle.Update();

            cookingRec.LearndDietMenu.Add(diet.Name);
            cookingRec.Update();

            session.SendBack("兑换成功！");
            return true;
        }

        [ModuleEnter(Command = "我的厨房", Description = "查看自己的厨房情况")]
        public bool MyKitchen(InboxSession session)
        {
            var cookingRec = CookingRecordDA.Get(session.User.ID);
            var level = CookingLevelSvc.LocationLevel(cookingRec.TotalPrice());

            var itemColle = ItemCollectionDA.Get(session.User.ID);
            var dietList = cookingRec.LearndDietMenu.Select
                (diet =>
                {
                    var Diet = CookingDietSvc[diet];
                    if (!Diet.Flavorings.IsNullOrEmpty() && !cookingRec.CheckFlavorings(Diet.Flavorings) ||
                        !Diet.Materials.IsNullOrEmpty() && !itemColle.CheckItem(Diet.Materials))
                    {
                        return $"{diet}(材料不足)";
                    }

                    return diet;
                });

            var buffer = new OutputBuffer(session);
            buffer.Add($"【{level.Name}(lv.{level.Level})】");
            buffer.AddPair(new Dictionary<string, string>
            {
                ["已学会的菜谱"] = string.Join("，", dietList),
                ["当前持有菜肴"] = string.Join("，", cookingRec.CookedDietDic.Select(p => $"{p.Key}*{p.Value}")),
                ["当前持有调味料"] = string.Join("，", cookingRec.FlavoringDic.Select(p => $"{p.Key}*{p.Value}")),
                ["推荐学习菜谱"] = $"【{CookingDietSvc.SuggestDiet(cookingRec.LearndDietMenu)?.Name}】"
            });
            buffer.Send();
            return true;
        }

        [ModuleEnter(Command = "菜谱总览", Description = "查看所有的菜谱")]
        public bool DietMenu(InboxSession session)
        {
            var cookingRec = CookingRecordDA.Get(session.User.ID);
            var allDiets = CookingDietSvc.DietList;

            var buffer = new OutputBuffer(session);
            buffer.Add(allDiets.Select(diet => $@"{diet.Name}{(cookingRec.LearndDietMenu.Contains(diet.Name)
                                                                   ? "(已学会)"
                                                                   : string.Empty)}:{string.Join(",", diet.Attributes)}"));
            buffer.Send();
            return true;
        }
    }
}